import java.util.ArrayList;

public class Neuronio {

	/**
	 * @author Danilo M. Gomes
	 * @see https://code.google.com/p/rna-pmc/
	 */

	ArrayList<Conexoes> conexoes_entrada = new ArrayList<Conexoes>();
	ArrayList<Conexoes> conexoes_saida = new ArrayList<Conexoes>();
	Funcao f_ativacao;
	int saida;

	/*
	 * Para cada Neuronio construido, devemos passar um conjunto de entradas
	 * Para a camada anterior(Perceptron eh, por si so, a camada anterior e
	 * inicial), inserimos os dados carregados do .TXT como valor da conexao
	 * sinaptica, para cada conexao. Criando assim uma conexao de entrada.
	 */
	public Neuronio(ArrayList<Entrada> entradas) {
		for (Entrada entrada : entradas) {
			Conexoes conexao = new Conexoes(entrada.getValor());
			this.conexoes_entrada.add(conexao);

		}

	}

	public void propagar(ArrayList<Conexoes> conexoes_saida) {
		if (this.avaliar() == true) {
			Reader arquivo = new Reader();
			for (Conexoes entrada : conexoes_entrada) {
				double valor = entrada.getValor();
				for (Conexoes saida : conexoes_saida) {
					/*
					 * Valor utilizado eh o dado da conexao da camada anterior.
					 * Cada Conexao Sinaptica possui um peso P e um dado D. Esse
					 * D eh o que esta sendo passado para a conexao posteior.
					 */
					saida.setValor(valor);
					arquivo.gravaArquivo(""+entrada.getPeso());
					arquivo.gravaArquivo("\n");
				}
			}
		}
		this.ajustar();

	}

	/*
	 * M�todo para retornar a somatoria dos valores de todas conex�es ligadas
	 * aquele neuronio.
	 */
	public double somatoria() {
		double resultado = 0;
		for (Conexoes conexao : conexoes_entrada) {
			double calc = conexao.getValor() * conexao.getPeso();
			resultado += calc;
		}
		return resultado;
	}

	/*
	 * Verificar se o valor da somatoria � suficiente para ativar o a
	 * propagacao. Verificar Funcao.java Condicao para ativacao eh x > 1 Se for,
	 * retorna TRUE.
	 */
	public boolean avaliar() {
		double resultado = this.somatoria();
		this.f_ativacao = new Funcao(resultado);
		if (this.f_ativacao.getAvaliacao() == true) {
			this.saida = 1;
			return true;
		}
		this.saida = 0;
		return false;
	}

	/*
	 * Verificar junto ao conjunto de treinamento a resposta esperada. Obter a
	 * resposta propagada(Na ultima camada, como eh um Perceptron, eh nessa)
	 * pelo Neuronio Comparar as duas e entao Incrementar ou Decrementar os
	 * pesos das Conexoes Sinapticas.
	 */
	public void ajustar() {
		for (Conexoes conexao : conexoes_entrada) {
			int resposta_dada = this.saida;
			int resposta_esperada;
			/*
			 * Acredito que tenha q ser um valor q possa ser comparado. 
			 */
			if (conexao.getDadosDeEntrada().getMereceCredito()) {
				resposta_esperada = 1;
			} else {
				resposta_esperada = 0;
			}
			if (respostas_dada > resposta_esperada) {
				conexao.decrementar();
			}

			else if (respostas_dada < resposta_esperada) {
				conexao.incrementar();
			}
		}
	}

}
